package com.byd.base;

import java.util.Set;
import java.util.WeakHashMap;
import android.app.Activity;
import android.app.Application;
import android.app.Application.ActivityLifecycleCallbacks;
import android.os.Bundle;
import com.byd.base.BaseActivity.Lifecycle;
import com.byd.model.DataBase;
import com.byd.model.MyThreadPool;
import com.byd.model.Path;
import com.byd.utils.Lg;

public class BaseApplication extends Application implements ActivityLifecycleCallbacks {
	private static final WeakHashMap<BaseActivity, Long> mWeakActicitys = new WeakHashMap<BaseActivity, Long>();

	@Override
	public void onCreate() {
		super.onCreate();
		MyUncaughtExceptionHandler.startWork(getApplicationContext());
		Path.init();
		DataBase.init();
		registerActivityLifecycleCallbacks(this);
	}

	@Override
	public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
		synchronized (mWeakActicitys) {
			mWeakActicitys.put((BaseActivity) activity, System.currentTimeMillis());
		}
	}

	@Override
	public void onActivityStarted(Activity activity) {
		// nothing
	}

	@Override
	public void onActivityResumed(Activity activity) {
		// nothing
	}

	@Override
	public void onActivityPaused(Activity activity) {
		// nothing
	}

	@Override
	public void onActivityStopped(Activity activity) {
		// nothing
	}

	@Override
	public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
		// nothing
	}

	@Override
	public void onActivityDestroyed(Activity activity) {
		synchronized (mWeakActicitys) {
			mWeakActicitys.remove(activity);
		}
		if(activity instanceof BaseActivity && ((BaseActivity) activity).isGcWhenDestroy()) {
			callGc(500, 3, 250);
		}
	}

	public static BaseActivity getLastActivity() {
		synchronized (mWeakActicitys) {
			final Set<BaseActivity> keys = mWeakActicitys.keySet();
			BaseActivity result = null;
			for (final BaseActivity activity : keys) {
				if(activity.getLifecycle() != Lifecycle.UNKNOWN && activity.getLifecycle() != Lifecycle.DESTROYED) {
					if(result == null) {
						result = activity;
					}
					if(activity.getActiveTime() > result.getActiveTime()) {
						result = activity;
					}
				}
			}
			return result;
		}
	}
	
	private static class Gc implements Runnable {
		private int delay;
		private int count;
		private int interval;

		Gc() {
			this(0, 1, 0);
		}

		Gc(int delay) {
			this(delay, 1, 0);
		}

		Gc(int delay, int count, int interval) {
			this.delay = delay;
			this.count = count;
			this.interval = interval;
		}

		@Override
		public void run() {
			try {
				if(delay > 0) {
					Thread.sleep(delay);
				}
				for (int i = 0; i < count; i++) {
					System.gc();
					if(i < count - 1 && interval > 0) {
						Thread.sleep(interval);
					}
				}
			}
			catch (Exception e) {
				Lg.printStackTrace(e);
			}
		}
	}

	public static void callGc() {
		MyThreadPool.postNewThread("gc", new Gc());
	}

	public static void callGc(int delay) {
		MyThreadPool.postNewThread("gc_" + delay, new Gc(delay));
	}

	public static void callGc(int delay, int count, int interval) {
		MyThreadPool.postNewThread("gc_" + delay + "_" + count + "_" + interval, new Gc(delay, count, interval));
	}

	public static void destroyAllActivitys() {
		final Set<BaseActivity> keys = mWeakActicitys.keySet();
		for (final BaseActivity activity : keys) {
			if(activity != null && !activity.isDestroyed()) {
				activity.finish();
			}
		}
	}
}
